import { Tabs } from 'antd';
import { useState, useEffect, useRef} from 'react';
import { useIntl } from 'umi';
import GrafanaWrap from '../../Monitor/grafana'


/**
 * 封装 useState，使其具有 getState 方法，保证在回调函数中获取到的 state 值是最新的
 * （由于闭包，直接在回调函数中使用state获取到的不是最新值）
 * @param {*} initVal
 * @reference https://www.haorooms.com/post/usegetstate_hooks
 * @returns
 */
const useGetState = (initVal) => {
    const [state, setState] = useState(initVal);
    const ref = useRef(initVal);
    const setStateCopy = (newVal) => {
        ref.current = newVal;
        setState(newVal);
    }
    const getState = () => ref.current;
    return [state, setStateCopy, getState];
}

/**
 * 多面板配置
{
    "menuName": "menu.app_observable.nginx",
    "type": "multiGrafanaPannel",
    "config": [
        {
            "pannelId": "nginx_monitor",
            "pannelName": "pages.app_observable.monitor_dashboard",
            "pannelUrl": "/grafana/d/6Mztrm4Ik/nginx"
        },
        {
            "pannelId": "nginx_event",
            "pannelName": "pages.app_observable.abnormal_events",
            "pannelUrl": "/grafana/d/HtuWUeSSz/nginx-event"
        }
    ]
}
 * @param {*} props 
 */
const MultiGrafanaPannel = (props) => {
    const intl = useIntl();
    let pannels = props.config
    let pannelMap = {}
    pannels.map((pannel) => {
        pannelMap[pannel.pannelId] = pannel
    })
    let pannelGetter = {}
    let pannelSetter = {}
    pannels.map((pannel) => {
        const [getter, setter] = useGetState(pannel.pannelUrl);
        pannelGetter[pannel.pannelId] = getter
        pannelSetter[pannel.pannelId] = setter
    })

    const [currentTab, setCurrentTab, getCurrentTab] = useGetState(pannels[0]["pannelId"]);

    useEffect(() => {
        const queryParams = !!props.location?.query ? props.location.query : {};
        if ('_currentTab' in queryParams) {
            let _currentTab = queryParams._currentTab;
            if (_currentTab in pannelGetter) {
                setCurrentTab(_currentTab);
            }
        }

        // queryParams to query string
        const queryStr = Object.keys(queryParams).map(key => key + '=' + queryParams[key]).join('&').trim();
        if (queryStr.length > 0) {
            for (let pannelId in pannelGetter) {
                pannelSetter[pannelId](pannelMap[pannelId]["pannelUrl"] + `?${queryStr}`);
            }
        }
    }, []);

    let items = pannels.map((pannel) => {
        return {
            label: intl.formatMessage({
                id: pannel.pannelName,
                defaultMessage: pannel.pannelName,
            }),
            key: pannel.pannelId,
            forceRender: true,
            children: (
                <div>
                    {
                        currentTab == pannel.pannelId ?
                            <GrafanaWrap
                                src={pannelGetter[pannel.pannelId]}
                                onUrlChange={newUrl => {
                                    if (newUrl.trim() == "about:blank") {
                                        return
                                    }
                                    if (getCurrentTab() == pannel.pannelId) {
                                        let targetPannelId = pannel.pannelId;
                                        for (let otherPannelId in pannelGetter) {
                                            if (otherPannelId == pannel.pannelId) {
                                                continue
                                            }
                                            pannelSetter[otherPannelId](newUrl.replace(pannelMap[pannel.pannelId]["pannelUrl"], pannelMap[otherPannelId]["pannelUrl"]));
                                            if (newUrl.indexOf(pannelMap[otherPannelId]["pannelUrl"]) >= 0) {
                                                targetPannelId = otherPannelId;
                                            }
                                        }
                                        if (targetPannelId != pannel.pannelId) {
                                            setCurrentTab(targetPannelId);
                                        }
                                    }
                                }}
                                urlChangeInvokeInterval={50}
                            />
                            :
                            <span>{pannel.pannelId}</span>
                    }
                </div>
            )
        }
    });

    return (
        <div>
            <Tabs
                activeKey={currentTab}
                tabPosition='left'
                items={items}
                onChange={(key) => {
                    setCurrentTab(key);
                }}
            />
        </div>
    )
};

export default MultiGrafanaPannel;